home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / fpoly256.zip / FX3DKIT.C < prev    next >
C/C++ Source or Header  |  1992-01-27  |  14KB  |  593 lines

  1. #include <bios.h>
  2. #include <dos.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. unsigned int dpaddr = 0;        /* video write base */
  7.  
  8. unsigned long l_hold, r_hold;          /* used to hold old x data for edge */
  9.  
  10. int l_clip = 0;         /* clipping rectangle for polys and lines */
  11. int r_clip = 319;       /* max. 0,319,0,199              */
  12. int t_clip = 0;
  13. int b_clip = 199;
  14.  
  15. typedef struct lp {           /* set of points for clipping or line dwg */
  16.             int x1, y1, x2, y2;
  17.           } lpoints;
  18.  
  19.  
  20.  
  21.  
  22. extern void far vsync();                /* pause till vert. retrace */
  23. extern void far vga_reg(int reg);     /* load VGA register:  */
  24.                     /* reg = reg# + 256*value */
  25.  
  26. extern void far load_color(int color);  /* load VGA color register */
  27. extern void far set_vmode(int mode);    /* set video mode thru BIOS */
  28. extern void far set_vpage(int page);    /* set video page thru BIOS */
  29.  
  30.  
  31. #define PUT 0        /* defines of VGA write modes */
  32. #define AND 1           /* for use with setup_hdwe()  */
  33. #define OR  2
  34. #define XOR 3
  35.  
  36. extern void far setup_hdwe(int mode);  /* setup VGA for bunch of line */
  37.                        /* or poly draws: once per set */
  38.  
  39. extern void far reset_hdwe();  /* reset VGA to BIOS state after drawing */
  40.  
  41.              /* clear video page to solid color: 10 mS */
  42.              /* returns -1 if bad page #         */
  43. extern int far clr_page(int page, int color);
  44.  
  45.             /* copy one page to another for use as */
  46.             /* background: 21 mS per call          */
  47.             /* returns -1 if bad page #            */
  48. extern int far copy_page(int source, int dest);
  49.  
  50.             /* fast VGA line draw: about 15600 24-pixel */
  51.             /* vectors/sec (horizontal much faster)     */
  52. extern void far vgaline(int x1, int y1, int x2, int y2, int color);
  53.  
  54.             /* line draw using lpoint structure   */
  55. void vgalines(lpoints *points, int color);
  56.  
  57.             /* Fast Cohen-Sutherland line clipper */
  58.             /* modifies data in points, returns   */
  59.             /* 0 if not clipped, 1 if clipped,    */
  60.             /* -1 if undrawable                   */
  61.             /* 2 - 10 uS per call                 */
  62. int clipper (lpoints far *points);
  63.  
  64.             /* does C-S clipping and draws line   */
  65.             /* returns same codes as C-S clipper  */
  66. int clipline (lpoints *points, int color);
  67.  
  68. #define NO_HOLD  0      /* values for hold in tpoly() */
  69. #define L_HOLD   1
  70. #define R_HOLD   2
  71. #define HOLD_ALL 3
  72. #define HOLD 0x8000     /* use in x1 or x2 to continue poly side */
  73.  
  74.             /* draws trapeziodal poly slice FAST   */
  75.             /* x1 is top left, x2 is top right,    */
  76.             /* y1 is top, y3 is bottom.  Clipping  */
  77.             /* is performed.  l_incr and r_incr    */
  78.             /* set slope of sides.               */
  79.             /* if x1 or x2 = HOLD, continues that  */
  80.             /* side from last tpoly call.  Use     */
  81.             /* bits in hold to ensure that needed  */
  82.             /* side data is good in previous tpoly */
  83. extern int far tpoly(int x1,int x2, long l_incr, long r_incr,
  84.                      int y1, int y3, int hold);
  85.  
  86.                    /* compute (x1-x2)/(y1-y2) << 16 */
  87.                    /* used for tpoly...             */
  88.                    /* returns x1-x2 if y1==y2       */
  89. extern long far compute_slope(int x1, int x2, int y1, int y2);
  90.  
  91. void set_gmode();              /* enters 320x200x16 mode, clears screen */
  92. void restore_gmode();          /* enters 320x200x16 mode w/o  clearing screen */
  93. void exit_gmode();             /* exits to text mode */
  94.  
  95. int set_drawpage(int page);        /* set page for drawing on (0-7)   */
  96.  
  97.              /* set displayed page: uses BIOS   */
  98.              /* call, so DON'T use in interrupt */
  99.              /* routines! If WAIT is 1, will    */
  100.              /* sync with vert. retrace (pause) */
  101. int set_vidpage(int page, int wait);
  102.  
  103.  
  104.                    /* draw and fill 3-sided polygon    */
  105.                    /* automatically clipped to bounds  */
  106.                    /* not a "pretty poly" fill, so     */
  107.                    /* sliver polys break up.           */
  108.                    /* 5800 polys/sec for 24x24         */
  109. poly3(int x1, int y1, int x2, int y2, int x3, int y3, int color);
  110.  
  111.             /* fastest triangle poly blitter */
  112.             /* points must be in CCW order   */
  113.             /* (clockwise before Y mirror)   */
  114.             /* and color must have been set  */
  115.             /* with load_color() before call */
  116.             /* NO CLIPPING AT ALL            */
  117. void fastri(int x1, int y1, int x2, int y2, int x3, int y3);
  118.  
  119.             /* N_SIDED POLY DRAW DONE WITH TRIANGLES */
  120.             /* pass pointers to X, Y coord arrays    */
  121.             /* and count.  No clipping, preset color */
  122.             /* with load_color()                     */
  123. void polynt(int *xcoords, int *ycoords, int count);
  124.  
  125.             /* draw and fill 3-sided polygon    */
  126.             /* automatically clipped to bounds  */
  127.             /* not a "pretty poly" fill, so     */
  128.             /* sliver polys break up.           */
  129.             /* will draw some concave polys OK  */
  130.             /* but can't be depended on esp.    */
  131.             /* if concavity is at top or bot.   */
  132.             /* 3800 30x30 polys/sec             */
  133. poly4(int x1, int y1, int x2, int y2, int x3, int y3,
  134.                     int x4, int y4, int color);
  135.  
  136.  
  137.  
  138. /************* GRAPHICS MODE CONTROL SUPPORT **************/
  139.  
  140. void set_gmode()        /* enters 320x200x256 mode, clears screen */
  141. {
  142.  set_vmode(0x14);
  143. }
  144.  
  145.  
  146. void restore_gmode()        /* enters 320x200x256 mode w/o  clearing screen */
  147. {
  148.  set_vmode(0x94);
  149. }
  150.  
  151.  
  152. void exit_gmode()        /* exits to text mode */
  153. {
  154.  set_vmode(0x02);
  155. }
  156.  
  157.  
  158. int set_drawpage(int page)      /* set page for drawing */
  159. {
  160.  if(page>3) return(-1);
  161.  dpaddr = 16000*page;
  162.  return(0);
  163. }
  164.  
  165.  
  166. int set_vidpage(int page, int wait)  /* set visible page, wait for vsync */
  167. {
  168.  if(page>3) return(-1);
  169.  set_vpage(page);
  170.  if(wait) vsync();
  171. }
  172.  
  173.  
  174. /******************* LINE DRAWING SUPPORT ***************/
  175.  
  176. void vgalines(lpoints *l, int color)
  177. {
  178.  vgaline(l->x1, l->y1, l->x2, l->y2, color);
  179. }
  180.  
  181.  
  182. int clipline(lpoints *l, int color)
  183. {
  184.  register int i;
  185.  
  186.  if ((i=clipper(l))==-1) return(i);
  187.  vgaline(l->x1, l->y1, l->x2, l->y2, color);
  188.  return(i);
  189. }
  190.  
  191.  
  192.  
  193. /*************** 3-SIDED POLYGON DRAW AND FILL ***************/
  194.  
  195. poly3(int x1, int y1, int x2, int y2, int x3, int y3, int color)
  196. {
  197.  register int i;
  198.  long s12, s23, s13;
  199.               /* find if all outside of window      */
  200.               /* sort of braindead partial clipping */
  201.               /* but it's fast and optimal for      */
  202.               /* small polys */
  203.  
  204.  i = r_clip;
  205.  if(!( x1<=i || x2<=i || x3<=i )) return(0);
  206.  
  207.  i = l_clip;
  208.  if(!( x1>=i || x2>=i || x3>=i )) return(0);
  209.  
  210.  i = b_clip;
  211.  if(!( y1<=i || y2<=i || y3<=i )) return(0);
  212.  
  213.  i = t_clip;
  214.  if(!( y1>=i || y2>=i || y3>=i )) return(0);
  215.  
  216.  if(y2<y1)       /* sort by vert pos'n */
  217.   {
  218.    i = y1;
  219.    y1 = y2;
  220.    y2 = i;
  221.    i = x1;
  222.    x1 = x2;
  223.    x2 = i;
  224.   }
  225.  
  226.  if(y3<y1)
  227.   {
  228.    i = y1;
  229.    y1 = y3;
  230.    y3 = i;
  231.    i = x1;
  232.    x1 = x3;
  233.    x3 = i;
  234.   }
  235.  
  236.  if(y3<y2)
  237.   {
  238.    i = y2;
  239.    y2 = y3;
  240.    y3 = i;
  241.    i = x2;
  242.    x2 = x3;
  243.    x3 = i;
  244.   }
  245.  
  246.  if(y3<t_clip || y1>b_clip)return(0);    /* all above or below clip area */
  247.  
  248.  if(y1==y2&&y2==y3) return;
  249.  
  250.  load_color(color);
  251.  
  252.  if(y1==y2)        /* case = 2 (flat top) */
  253.   {
  254.    if(x2<x1)
  255.     {
  256.      i = x1;
  257.      x1 = x2;
  258.      x2 = i;
  259.     }
  260.    s23 = compute_slope(x2,y2,x3,y3);
  261.    s13 = compute_slope(x1,y1,x3,y3);
  262.    tpoly(x1,x2,s13,s23,y1,y3,NO_HOLD);
  263.   }
  264.  else if(y2==y3)     /* case = 1 (flat bottom)*/
  265.   {
  266.    if(x3<x2)
  267.     {
  268.      i = x2;            /* sort bottom sides */
  269.      x2 = x3;
  270.      x3 = i;
  271.     }
  272.    s12 = compute_slope(x1,y1,x2,y2);
  273.    s13 = compute_slope(x1,y1,x3,y3);
  274.    tpoly(x1,x1,s12,s13,y1,y3,NO_HOLD);
  275.   }
  276.  else
  277.   {
  278.    s12 = compute_slope(x1,y1,x2,y2);
  279.    s23 = compute_slope(x2,y2,x3,y3);
  280.    s13 = compute_slope(x1,y1,x3,y3);
  281.  
  282.    if(s12>s13)     /* case = 4 (3rd point on right) */
  283.     {
  284.      tpoly(x1,x1,s13,s12,y1,y2,L_HOLD);
  285.      tpoly(0x8000,x2,s13,s23,y2,y3,NO_HOLD);
  286.     }
  287.    else         /* case = 3 (3rd point on left)  */
  288.     {
  289.      tpoly(x1,x1,s12,s13,y1,y2,R_HOLD);
  290.      tpoly(x2,0x8000,s23,s13,y2,y3,NO_HOLD);
  291.     }
  292.   }
  293. }
  294.  
  295.  
  296.  
  297. /******************* 4-SIDED CONVEX POLY DRAW AND FILL **************/
  298.  
  299. /* draw quad poly-- MUST BE CONVEX */
  300. /* will draw some concave polys OK */
  301. /* but can't be depended on esp.   */
  302. /* if concavity is at top or bot.  */
  303.  
  304. poly4(int x1, int y1, int x2, int y2, int x3, int y3,
  305.                  int x4, int y4, int color)
  306. {
  307.  register int i;
  308.  long s12, s13, s24, s14, s23 ,s34;
  309.  
  310.               /* find if all outside of window      */
  311.               /* sort of braindead partial clipping */
  312.               /* but it's fast and optimal for      */
  313.               /* small polys */
  314.  i = r_clip;
  315.  if(!( x1<=i || x2<=i || x3<=i || x4<=i )) return(0);
  316.  
  317.  i = l_clip;
  318.  if(!( x1>=i || x2>=i || x3>=i || x4>=i )) return(0);
  319.  
  320.  i = b_clip;
  321.  if(!( y1<=i || y2<=i || y3<=i || y4<=i )) return(0);
  322.  
  323.  i = t_clip;
  324.  if(!( y1>=i || y2>=i || y3>=i || y4>=i )) return(0);
  325.  
  326.  if(y2<y1)       /* sort by vert pos'n             */
  327.   {             /* an unrolled bubble sort        */
  328.    i = y1;      /* early termination not worth it */
  329.    y1 = y2;
  330.    y2 = i;
  331.    i = x1;
  332.    x1 = x2;
  333.    x2 = i;
  334.   }
  335.  
  336.  if(y3<y1)
  337.   {
  338.    i = y1;
  339.    y1 = y3;
  340.    y3 = i;
  341.    i = x1;
  342.    x1 = x3;
  343.    x3 = i;
  344.   }
  345.  
  346.  if(y4<y1)
  347.   {
  348.    i = y1;
  349.    y1 = y4;
  350.    y4 = i;
  351.    i = x1;
  352.    x1 = x4;
  353.    x4 = i;
  354.   }
  355.  
  356.  if(y3<y2)
  357.   {
  358.    i = y2;
  359.    y2 = y3;
  360.    y3 = i;
  361.    i = x2;
  362.    x2 = x3;
  363.    x3 = i;
  364.   }
  365.  
  366.  if(y4<y2)
  367.   {
  368.    i = y2;
  369.    y2 = y4;
  370.    y4 = i;
  371.    i = x2;
  372.    x2 = x4;
  373.    x4 = i;
  374.   }
  375.  
  376.  if(y4<y3)
  377.   {
  378.    i = y3;
  379.    y3 = y4;
  380.    y4 = i;
  381.    i = x3;
  382.    x3 = x4;
  383.    x4 = i;
  384.   }
  385.  
  386.  load_color(color);             /* set VGA color register */
  387.  
  388.  if(y1==y2) goto case_a;
  389.  if(y2==y3) goto case_b;
  390.  if(y3==y4) goto case_c;
  391.  if(y4==y1) return(0);        /* invisible h. line poly: exit */
  392.  goto case_d;
  393.  
  394. case_a:                         /* flat top */
  395.  if(y2!=y3) goto case_e;
  396.  if(y3==y4) return(0);        /* invisible line */
  397.  
  398.  if(x2<x1)            /* sort x1 lowest, x3 highest */
  399.   {
  400.    i = x1;
  401.    x1 = x2;
  402.    x2 = i;
  403.    i = y1;
  404.    y1 = y2;
  405.    y2 = i;
  406.   }
  407.  if(x3<x2)
  408.   {
  409.    x3 = x2;
  410.    y3 = x2;
  411.   }
  412.  
  413.  s14 = compute_slope(x1,y1,x4,y4);    /* combine into flat-top tri */
  414.  s34 = compute_slope(x3,y3,x4,y4);
  415.  tpoly(x1,x3,s14,s34,y1,y4,NO_HOLD);
  416.  return(0);
  417.  
  418. case_e:                         /* flat top and bottom */
  419.  if(y3!=y4) goto case_f;
  420.  
  421.  if(x2<x1)            /* sort x1 lowest, x2 highest */
  422.   {
  423.    i = x1;
  424.    x1 = x2;
  425.    x2 = i;
  426.    i = y1;
  427.    y1 = y2;
  428.    y2 = i;
  429.   }
  430.  
  431.  if(x4<x3)            /* sort x3 lowest, x4 highest */
  432.   {
  433.    i = x3;
  434.    x3 = x4;
  435.    x4 = i;
  436.    i = y3;
  437.    y3 = y4;
  438.    y4 = i;
  439.   }
  440.  
  441.  s13 = compute_slope(x1,y1,x3,y3);    /* combine into parallelogram */
  442.  s24 = compute_slope(x2,y2,x4,y4);
  443.  tpoly(x1,x2,s13,s24,y1,y4,NO_HOLD);
  444.  return(0);
  445.  
  446. case_f:         /* flat-top only */
  447.  
  448.  if(x2<x1)            /* sort x1 lowest, x2 highest */
  449.   {
  450.    i = x1;
  451.    x1 = x2;
  452.    x2 = i;
  453.    i = y1;
  454.    y1 = y2;
  455.    y2 = i;
  456.   }
  457.  
  458.  if(x4<x3)                      /* left below right bottom */
  459.   {
  460.    s14 = compute_slope(x1,y1,x4,y4);
  461.    s23 = compute_slope(x2,y2,x3,y3);
  462.    tpoly(x1,x2,s14,s23,y1,y3,L_HOLD);
  463.    s34 = compute_slope(x3,y3,x4,y4);
  464.    tpoly(HOLD,x3,s14,s34,y3,y4,NO_HOLD);
  465.   }
  466.  else                          /* right below left bottom */
  467.   {
  468.    s13 = compute_slope(x1,y1,x3,y3);
  469.    s24 = compute_slope(x2,y2,x4,y4);
  470.    tpoly(x1,x2,s13,s24,y1,y3,R_HOLD);
  471.    s34 = compute_slope(x3,y3,x4,y4);
  472.    tpoly(x3,HOLD,s34,s24,y3,y4,NO_HOLD);
  473.   }
  474.  return(0);
  475.  
  476. case_b:                         /* sides equal height */
  477.  if(y3!=y4) goto case_g;        /* not triangular? */
  478.  
  479.  if(x3<x2)            /* sort x2 lowest, x4 highest */
  480.   {
  481.    i = x1;
  482.    x2 = x3;
  483.    x3 = i;
  484.    i = y2;
  485.    y2 = y3;
  486.    y3 = i;
  487.   }
  488.  if(x4<x3)
  489.   {
  490.    x4 = x3;
  491.    y4 = x3;
  492.   }
  493.  
  494.  s12 = compute_slope(x1,y1,x2,y2);    /* combine into flat-bottom tri */
  495.  s14 = compute_slope(x1,y1,x4,y4);
  496.  tpoly(x1,x1,s12,s14,y1,y4,NO_HOLD);
  497.  return(0);
  498.  
  499. case_g:        /* diamond */
  500.  
  501.  if(x3<x2)            /* sort x2 lowest, x3 highest */
  502.   {
  503.    i = x1;
  504.    x2 = x3;
  505.    x3 = i;
  506.    i = y2;
  507.    y2 = y3;
  508.    y3 = i;
  509.   }
  510.  s12 = compute_slope(x1,y1,x2,y2);    /* draw upper, lower diamond */
  511.  s13 = compute_slope(x1,y1,x3,y3);
  512.  tpoly(x1,x1,s12,s13,y1,y2,NO_HOLD);
  513.  s24 = compute_slope(x2,y2,x4,y4);
  514.  s34 = compute_slope(x3,y3,x4,y4);
  515.  tpoly(x2,x3,s24,s34,y2,y4,NO_HOLD);
  516.  return(0);
  517.  
  518. case_c:
  519.  /* flat-bottom only */
  520.  
  521.  if(x4<x3)            /* sort x3 lowest, x4 highest */
  522.   {
  523.    i = x3;
  524.    x3 = x4;
  525.    x4 = i;
  526.    i = y3;
  527.    y3 = y4;
  528.    y4 = i;
  529.   }
  530.  
  531.  if(x1<x2)                     /* left above right top */
  532.   {
  533.    s12 = compute_slope(x1,y1,x2,y2);
  534.    s13 = compute_slope(x1,y1,x3,y3);
  535.    tpoly(x1,x1,s13,s12,y1,y2,L_HOLD);
  536.    s24 = compute_slope(x2,y2,x4,y4);
  537.    tpoly(HOLD,x2,s13,s24,y2,y4,NO_HOLD);
  538.   }
  539.  else                          /* right above left top */
  540.   {
  541.    s12 = compute_slope(x1,y1,x2,y2);
  542.    s14 = compute_slope(x1,y1,x4,y4);
  543.    tpoly(x1,x1,s12,s14,y1,y2,R_HOLD);
  544.    s23 = compute_slope(x2,y2,x3,y3);
  545.    tpoly(x2,HOLD,s23,s14,y2,y3,NO_HOLD);
  546.   }
  547.  return(0);
  548.  
  549. case_d:        /* no regularities */
  550.  
  551.  s12 = compute_slope(x1,y1,x2,y2);
  552.  s13 = compute_slope(x1,y1,x3,y3);
  553.  s34 = compute_slope(x3,y3,x4,y4);
  554.  s14 = compute_slope(x1,y1,x4,y4);
  555.  
  556.  if(s12<s13)        /* p2 at left */
  557.   {
  558.    if(s14>s34)          /* p2,p3 on opposite sides */
  559.     {
  560.      s24 = compute_slope(x2,y2,x4,y4);
  561.      tpoly(x1,x1,s12,s13,y1,y2,R_HOLD);
  562.      tpoly(x2,HOLD,s24,s13,y2,y3,L_HOLD);
  563.      tpoly(HOLD,x3,s24,s34,y3,y4,NO_HOLD);
  564.     }
  565.    else
  566.     {
  567.      s23 = compute_slope(x2,y2,x3,y3);
  568.      tpoly(x1,x1,s12,s14,y1,y2,R_HOLD);
  569.      tpoly(x2,HOLD,s23,s14,y2,y3,R_HOLD);
  570.      tpoly(x3,HOLD,s34,s14,y3,y4,NO_HOLD);
  571.     }
  572.   }
  573.  else
  574.   {
  575.    if(s14<s34)          /* p2,p3 on opposite sides */
  576.     {
  577.      tpoly(x1,x1,s13,s12,y1,y2,L_HOLD);
  578.      s24 = compute_slope(x2,y2,x4,y4);
  579.      tpoly(HOLD,x2,s13,s24,y2,y3,R_HOLD);
  580.      tpoly(x3,HOLD,s34,s24,y3,y4,NO_HOLD);
  581.     }
  582.    else
  583.     {
  584.      s23 = compute_slope(x2,y2,x3,y3);
  585.      tpoly(x1,x1,s14,s12,y1,y2,L_HOLD);
  586.      tpoly(HOLD,x2,s14,s23,y2,y3,L_HOLD);
  587.      tpoly(HOLD,x3,s14,s34,y3,y4,NO_HOLD);
  588.     }
  589.   }
  590.  return(0);
  591. }
  592.  
  593.